package com.dartfar.workflow.service;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.jbpm.api.HistoryService;
import org.jbpm.api.TaskService;
import org.jbpm.api.history.HistoryActivityInstance;
import org.jbpm.api.history.HistoryActivityInstanceQuery;
import org.jbpm.api.history.HistoryDetail;
import org.jbpm.api.history.HistoryDetailQuery;
import org.jbpm.api.task.Task;
import org.jbpm.pvm.internal.history.model.HistoryActivityInstanceImpl;
import org.jbpm.pvm.internal.history.model.HistoryCommentImpl;
import org.jbpm.pvm.internal.history.model.HistoryTaskImpl;
import org.jbpm.pvm.internal.history.model.HistoryTaskInstanceImpl;
import org.springframework.stereotype.Component;

import com.dartfar.base.dao.DaoUtil;
import com.dartfar.base.model.BaseEntity;
import com.dartfar.base.model.Person;
import com.dartfar.util.DateUtils;
import com.dartfar.util.EntityUtils;
import com.dartfar.util.StringUtils;
import com.dartfar.workflow.model.WorkflowProcessFunMount;
import com.dartfar.workflow.vo.WorkflowHistoryVo;

@Component("workflowHistoryService")
public class WorkflowHistoryServiceImpl implements WorkflowHistoryService {

	static Logger logger = Logger.getLogger(WorkflowHistoryServiceImpl.class);

	@Resource
	private DaoUtil<WorkflowProcessFunMount> workflowProcessFunMountDaoUtil;
	@Resource
	private DaoUtil<Person> personDaoUnit;
	@Resource
	private DaoUtil<BaseEntity> baseEntityDaoUtil;
	@Resource
	private HistoryService historyService;
	@Resource
	private TaskService taskService;
	
	@Override
	public List<WorkflowHistoryVo> findHistory(int wpfmId,  int id, Boolean isAsc) {
		// TODO Auto-generated method stub
		//判断流程是否存在
		WorkflowProcessFunMount processFunMount = (WorkflowProcessFunMount) workflowProcessFunMountDaoUtil.get("from WorkflowProcessFunMount w where w.id = " + wpfmId);
		if(processFunMount == null){
			logger.info("此流程不存在.");
			return null;
		}
		
		String modelName = processFunMount.getModelName();
		
		// 声明历史查询对象
		HistoryActivityInstanceQuery actQuery = historyService.createHistoryActivityInstanceQuery(); 
		HistoryDetailQuery detailQuery = historyService.createHistoryDetailQuery(); // 历史详情表查寻
		List<WorkflowHistoryVo> historys = new ArrayList<WorkflowHistoryVo>();
		// 拿到piid，流程实例的ID
		String piid = getProcessInstanceIdByModelInfo(modelName, id);
		if (StringUtils.isNotEmpty(piid)) {
			//加入查询条件
			actQuery.processInstanceId(piid);
			if(isAsc){
				actQuery.orderAsc("startTime");
			}else{
				actQuery.orderDesc("startTime");
			}
			List<HistoryActivityInstance> list = actQuery.list();
			for (int i = 0; i < list.size(); i++) {
				//得到活动历史记录
				HistoryActivityInstanceImpl haii = (HistoryActivityInstanceImpl) list.get(i);
				WorkflowHistoryVo log = new WorkflowHistoryVo();
				//赋值操作
				log.setNodeName(haii.getActivityName()); // 活动名称
				log.setTransCode(haii.getTransitionName());	//推进方式
				log.setStartTime(DateUtils.formatDateTime(haii.getStartTime())); // 活动开始时间
				log.setEndTime(DateUtils.formatDateTime(haii.getEndTime())); // 活动结束时间
				//拿到任务当前用时 如果结束时间为null则代表任务未结束
				if (null != haii.getEndTime()) {
					log.setDuration(haii.getDuration() / 1000 + "秒");
				} else {
					Long duration = System.currentTimeMillis() - haii.getStartTime().getTime();	
					log.setDuration(duration / 1000 + "秒");
				}
				if("decision".equalsIgnoreCase(haii.getType())){
					continue;
				}
				// 如果是task类型节点，才有以下信息
				if ("task".equalsIgnoreCase(haii.getType())) {
					log.setTypeDesc("人工任务");
					log.setTransCode(haii.getTransitionName());
					HistoryTaskInstanceImpl hti = (HistoryTaskInstanceImpl) haii;
					HistoryTaskImpl historyTask = hti.getHistoryTask();
					if (null != historyTask) {
						String personId = historyTask.getAssignee();
						if (StringUtils.isNotEmpty(personId)) {
							Person person = (Person) personDaoUnit.get("from Person p where p.personId = " + Integer.valueOf(personId));
							//Person person = (Person) pcManagerTemplate.getEntityByHql(" from EndUser where userCode='"+userCode+"'");
							if (null != person) {
								log.setAssignee(person.getName());
								log.setAssigneeCode(personId);
							} else {
								log.setAssignee("未知用户");
								log.setAssigneeCode(personId);
							}
					
						} else {
							// 正在执行的任务
							Task task = taskService.getTask(historyTask.getId());
							if (null != task) {
								personId = task.getAssignee();
								if (StringUtils.isNotEmpty(personId)) {
									Person person = (Person) personDaoUnit.get("from Person p where p.personId = " + Integer.valueOf(personId));
									//EndUser user = (EndUser) pcManagerTemplate.getEntityByHql(" from EndUser where userCode='"+userCode+"'");
									if (null != person) {
										log.setAssignee(person.getName());
										log.setAssigneeCode(personId);
									}
								}else{
									log.setAssignee("未知用户");
									log.setAssigneeCode(personId);
								}
							}
						}
					}
					detailQuery.taskId(historyTask.getId());
					List<HistoryDetail> details = detailQuery.list();
					for(HistoryDetail detail : details) {
						if(detail instanceof HistoryCommentImpl) {
							HistoryCommentImpl comments = (HistoryCommentImpl) detail;
							if(StringUtils.isNotEmpty(comments.getMessage())){
							log.setComments(log.getComments() + comments.getMessage().trim());
							}
						}
					}
				}
				historys.add(log);
			}
		}
		return historys;
	}
	
	/**
	 * 根据model信息查询到piid值
	 * @param modelName
	 * @param idValue
	 * @return
	 */
	public String getProcessInstanceIdByModelInfo(String modelName, int id) {
		Class clazz = null;
		try {
			clazz = Class.forName(modelName);
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		BaseEntity entity = (BaseEntity)baseEntityDaoUtil.get(id, clazz);
		//BaseEntity entity = (BaseEntity) pcManagerTemplate.findById(clazz,idValue);
		if (EntityUtils.isNotNull(entity)) {
			return entity.getProcessInstanceId();
		} else {
			System.out.println("实体未找到");
			return null;
		}
	}

}
